<?php
    class WZ_List
    {
        static $_instance;
        static $_model;
        static $_table;
        static $_service;
        static $_fields;
        static $_session;
        static $_db;
        static $_itemsByPage;
        static $_defaultOrderField;
        static $_defaultOrder;
        static $_defaultRender;
        static $_total;
        static $_numpages;
        static $_query;
        static $_render;
        static $_class;
        static $_pagination;
        
        public static function factory($obj)
        {
            static::$_class = $class = get_class($obj);
            static::$_table = $table = \WZ_Inflector::lower(end(explode('_', $class)));
            static::$_service = $serviceClass = str_replace('WZList_', 'WZService_', $class);
            static::$_model = str_replace('WZList_', 'WZModel_', $class);
            static::$_session = $session = \WZ_Session::getInstance('WZListSession_' . $table);
            $serviceClass::init();
            static::$_db = \Loader::WZ_Activerecord(new static::$_model);
            static::$_total = static::$_db->getTotal();
            static::$_numpages = ceil(static::$_total / static::$_itemsByPage);
            static::$_query = $session->getFilterquery();;
            if (!in_array($table, static::$_instance)) {
                static::$_instance[$table]  = new static;
            }
            if (!static::$_instance[$table] instanceof self) {
				static::$_instance[$table]  = new self;
			}
            return static::$_instance[$table];
        }
        
        public static function clearFilterQuery()
        {
            static::$_session = static::$_session->delete();
        }
        
        public static function render($options = array())
        {
            if (isset($options['page'])) {
                $page = $options['page'];
            } else {
                $page = 1;
            }
            
            if (isset($options['orderField'])) {
                $orderField = $options['orderField'];
            } else {
                $orderField = static::$_defaultOrderField;
            }
            
            if (isset($options['order'])) {
                $order = $options['order'];
            } else {
                $order = static::$_defaultOrder;
            }
            
            if (isset($options['render'])) {
                $render = $options['render'];
            } else {
                $render = static::$_defaultRender;
            }
            
            $query = static::$_query;
            if (null === $query) {
                $query = "1 = 1";
                static::$_session->setFilterquery($query);
            }
            
            $listFields = array();
            foreach (static::$_fields as $field) {
                extract($field);
                if (true === $onList) {
                    $listFields[] = $name;
                }
            }
            
            $primary = static::$_db->getPrimary();
            if (!in_array($primary, $listFields)) {
                $listFields[] = $primary;
            }
            
            $listFields = implode(', ', $listFields);
            
            $offset = (static::$_itemsByPage * $page) - static::$_itemsByPage;
            
            $q = "SELECT $listFields FROM " . static::$_table . " WHERE $query ORDER BY $orderField $order";
            $res = static::$_db->query($q, false);
            
            $pagination = \WZ::pagination($res, $page, static::$_itemsByPage);
            $pages = $pagination->getPages();
            if ($pages->pageCount > 1) {
                static::pagination($pages);
            }
            
            $pageCollection = $pagination->getItemsByPage($page);
            
            if ($render == 'array') {
                static::$_render = $pageCollection;
            } elseif ($render == 'html') {
                static::html($pageCollection);
            }
            
            return self::$_instance[self::$_table];
        }
        
        public static function pagination($pages)
        {
            $first = $pages->first;
            $next = $pages->next;
            $previous = $pages->previous;
            $last = $pages->last;
            $current = $pages->current;
            $pagesInRange = $pages->pagesInRange;
            $html = '<ul class="pagination paginationD paginationD09">
            <li><a href="#" class="first">&lt;&lt;</a></li>
            <li><a href="#" class="previous">&lt;</a></li>';
            foreach ($pagesInRange as $itemPage) {
                if ($itemPage == $current) {
					$html .= '<li><a href="#" class="current">' . $itemPage . '</a></li>';
                } else {
					$html .= '<li><a href="#">' . $itemPage . '</a></li>';
                }
            }
            $html .= '<li><a href="#" class="next">&gt;</a></li>
            <li><a href="#" class="last">&gt;&gt;</a></li>
            </ul>';
            static::$_pagination = $html;
        }
        
        public static function html($collection)
        {
            $class = static::$_class;
            $html = '';
            if (null !== static::$_pagination) {
                $html .= static::$_pagination;
                $html .= '<div class="sep"></div>';
            }
            $html .= '<table class="list">';
            $html .= '<tr>';
            $listFields = array();
            $listFieldsContent = array();
            foreach (static::$_fields as $field) {
                extract($field);
                if (true === $onList) {
                    $html .= '<th>' . \WZ_Inflector::clean($label) . '</th>';
                    $listFields[] = $name;
                    $listFieldsContent[] = $content;
                }
            }
            $html .= '</tr>';
            
            $i = 0;
            foreach ($collection as $row) {
                if ($i % 2 == 0) {
                    $html .= '<tr>';
                } else {
                    $html .= '<tr class="odd">';
                }
                $j = 0;
                foreach ($listFields as $field) {
                    unset($content);
                    unset($value);
                    $content = $listFieldsContent[$j];
                    if ($content == 'self') {
                        $value = $row[$field];
                    } else {
                        $value = $class::$content($row[$field]);
                    }
                    $html .= '<td>' . \WZ_Inflector::clean($value) . '</td>';
                    $j++;
                }
                $html .= '</tr>';
                $i++;
            }
            
            $html .= '</table>';
            if (null !== static::$_pagination) {
                $html .= '<div class="sep"></div>';
                $html .= static::$_pagination;
            }
            static::$_render = $html;
        }
    }